[READ-ONLY] Mirror of https://github.com/flo-bit/skywatched. review movies and tv shows, based on at proto skywatched.app
0

Configure Feed

Select the types of activity you want to include in your feed.

skywatched / src / routes / game / [kind] / [id] / [kind2] / [id2] / [counter] / +page.svelte
7.3 kB 206 lines
1<script lang="ts"> 2 import { type PageData } from './$types'; 3 import { cn, nameToId } from '$lib/utils'; 4 5 import Container from '$lib/Components/Layout/Container.svelte'; 6 import Avatar from '$lib/Components/User/Avatar.svelte'; 7 import { page } from '$app/stores'; 8 import { watchedItems } from '$lib/state/user.svelte'; 9 import { rateMovieModal } from '$lib/state/modals.svelte'; 10 11 let { data }: { data: PageData } = $props(); 12</script> 13 14<svelte:head> 15 <title>{data.result.title ?? data.result.name ?? ''} | skywatched</title> 16 17 <meta 18 name="description" 19 content={`Rate and review "${data.result.title ?? data.result.name ?? ''}" on skywatched`} 20 /> 21 22 <meta property="og:url" content={$page.url.href} /> 23 <meta property="og:type" content="website" /> 24 <meta 25 property="og:title" 26 content="{data.result.title ?? data.result.name ?? ''} | skywatched.app" 27 /> 28 <meta 29 property="og:description" 30 content={`Rate and review "${data.result.title ?? data.result.name ?? ''}" on skywatched`} 31 /> 32 <meta property="og:image" content="{$page.url.href}/og.png" /> 33 34 <meta name="twitter:card" content="summary_large_image" /> 35 <meta property="twitter:domain" content="skywatched.app" /> 36 <meta property="twitter:url" content={$page.url.href} /> 37 <meta 38 name="twitter:title" 39 content="{data.result.title ?? data.result.name ?? ''} | skywatched.app" 40 /> 41 <meta 42 name="twitter:description" 43 content={`Rate and review "${data.result.title ?? data.result.name ?? ''}" on skywatched`} 44 /> 45 <meta name="twitter:image" content="{$page.url.href}/og.png" /> 46</svelte:head> 47 48{#snippet buttons()} 49 {#if data.user && !watchedItems.hasRated(data.result)} 50 <button 51 class={cn( 52 'inline-flex items-center gap-2 rounded-md bg-white/10 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm transition-all duration-75 hover:bg-white/20 ', 53 watchedItems.hasRated(data.result) 54 ? 'bg-green-500/10 text-green-400 hover:bg-green-500/20' 55 : '' 56 )} 57 onclick={() => { 58 rateMovieModal.show({ 59 movieId: data.result.movieId, 60 showId: data.result.showId, 61 kind: data.result.movieId ? 'movie' : 'tv', 62 name: data.result.original_title ?? data.result.original_name, 63 posterPath: data.result.poster_path, 64 currentRating: watchedItems.getRating(data.result)?.rating ?? 0, 65 currentReview: watchedItems.getRating(data.result)?.ratingText ?? '' 66 }); 67 }} 68 > 69 rate {data.kind === 'movie' ? 'movie' : 'show'} 70 </button> 71 {/if} 72{/snippet} 73 74<div class="fixed inset-0 h-full w-full bg-black/50"></div> 75 76<Container class="relative z-10 pb-8 pt-4"> 77 <div class="flex justify-center gap-4 px-4 pt-8"> 78 <div class="flex-column"> 79 {#if data.kind === 'cast'} 80 <div class="text-center text-sm font-medium">Cast1</div> 81 <Avatar 82 src={data.personDetails.profile_path 83 ? 'https://image.tmdb.org/t/p/w500' + data.personDetails.profile_path 84 : undefined} 85 size="size-44" 86 /> 87 {:else} 88 <div class="text-center text-sm font-medium">Movie1</div> 89 <img 90 src="https://image.tmdb.org/t/p/w500{data.result.poster_path}" 91 alt="" 92 class="poster h-36 w-24 shrink-0 rounded-lg border border-white/10 sm:h-64 sm:w-44" 93 style:--name={`poster-${data.result.id}`} 94 /> 95 {/if} 96 </div> 97 <div class="flex-column"> 98 {#if data.kind2 === 'cast'} 99 <div class="text-center text-sm font-medium">Cast2</div> 100 <Avatar 101 src={data.person2Details.profile_path 102 ? 'https://image.tmdb.org/t/p/w500' + data.person2Details.profile_path 103 : undefined} 104 size="size-44" 105 /> 106 {:else} 107 <div class="text-center text-sm font-medium">Movie2</div> 108 <img 109 src="https://image.tmdb.org/t/p/w500{data.result2.poster_path}" 110 alt="" 111 class="poster h-36 w-24 shrink-0 rounded-lg border border-white/10 sm:h-64 sm:w-44" 112 style:--name={`poster-${data.result2.id}`} 113 /> 114 {/if} 115 </div> 116 </div> 117 118 <div class="px-4 pt-4 text-sm text-white"> 119 <div class="mb-4 flex gap-2 sm:hidden"> 120 {@render buttons()} 121 </div> 122 </div> 123 124 {#if data.cast.length > 0} 125 <div class="flex flex-col gap-x-6 px-4 pb-8 pt-4 text-sm text-white"> 126 {#if data.kind === 'cast'} 127 <div class="text-center text-sm font-medium">Movies of {data.personDetails.name}</div> 128 <div class={cn('flex justify-start gap-x-6 overflow-x-auto')}> 129 {#each data.combinedCredits as castMember} 130 <a 131 href={`/game/movie/${castMember.id}-${castMember.title ?? castMember.name}/${data.kind2}/${data.ids2}-/${parseInt(data.couter) + 1}`} 132 class="flex flex-col items-center gap-1" 133 > 134 <img 135 src="https://image.tmdb.org/t/p/w342{castMember.poster_path}" 136 alt="movie poster for {castMember.title ?? castMember.name}" 137 class="poster size-32 w-32 object-cover object-center lg:size-full" 138 /> 139 <div class="size-32 text-center text-sm font-medium"> 140 {castMember.title ?? castMember.name} 141 </div> 142 </a> 143 {/each} 144 </div> 145 {:else} 146 <div class="text-center text-sm font-medium">cast of {data.result.title}</div> 147 <div class={'justify-left flex gap-x-6 overflow-x-auto'}> 148 {#each data.cast as castMember} 149 <a 150 href={`/game/cast/${castMember.id}-${nameToId(castMember.name)}/${data.kind2}/${data.ids2}-/${parseInt(data.couter) + 1}`} 151 class="flex flex-col items-center gap-1" 152 > 153 <Avatar 154 src={castMember.profile_path 155 ? 'https://image.tmdb.org/t/p/w500' + castMember.profile_path 156 : undefined} 157 size="size-32" 158 /> 159 <div class="text-center text-xs font-medium">{castMember.name}</div> 160 <div class="text-center text-xs text-base-400">{castMember.character}</div> 161 </a> 162 {/each} 163 </div> 164 {/if} 165 {#if data.kind2 === 'cast'} 166 <div class="text-center text-sm font-medium">Movies of {data.person2Details.name}</div> 167 <div class={cn('flex gap-x-6 overflow-x-auto')}> 168 {#each data.combinedCredits2 as castMember} 169 <a 170 href={`/game/${data.kind}/${data.ids}-/movie/${castMember.id}-${castMember.title ?? castMember.name}/${parseInt(data.couter) + 1}`} 171 class="flex flex-col items-center gap-1" 172 > 173 <img 174 src="https://image.tmdb.org/t/p/w342{castMember.poster_path}" 175 alt="movie poster for {castMember.title ?? castMember.name}" 176 class="poster w-500 object-cover object-center lg:size-full" 177 /> 178 <div class="size-32 text-center text-sm font-medium"> 179 {castMember.title ?? castMember.name} 180 </div> 181 </a> 182 {/each} 183 </div> 184 {:else} 185 <div class="text-center text-sm font-medium">Cast of {data.result2.title}</div> 186 <div class={'justify-right flex gap-x-6 overflow-x-auto'}> 187 {#each data.cast2 as castMember} 188 <a 189 href={`/game/${data.kind}/${data.ids}-/cast/${castMember.id}-${castMember.title ?? castMember.name}/${parseInt(data.couter) + 1}`} 190 class="flex flex-col items-center gap-1" 191 > 192 <Avatar 193 src={castMember.profile_path 194 ? 'https://image.tmdb.org/t/p/w500' + castMember.profile_path 195 : undefined} 196 size="size-32" 197 /> 198 <div class="text-center text-xs font-medium">{castMember.name}</div> 199 <div class="text-center text-xs text-base-400">{castMember.character}</div> 200 </a> 201 {/each} 202 </div> 203 {/if} 204 </div> 205 {/if} 206</Container>